package com.lizemin;

import com.lizemin.entity.Student;
import com.lizemin.entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.query.Query;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;

/**
 * @author: lizemin
 * @version: 1.0
 */
public class HQLtest {

    Session session = null;
    Transaction tx = null;

    @Before
    public void init(){
        // A SessionFactory is set up once for an application!
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml") // configures settings from hibernate.cfg.xml
                .build();
        SessionFactory sessionFactory = new MetadataSources(registry)
                .buildMetadata()
                .buildSessionFactory();
        //创建SQL session连接
        session = sessionFactory.openSession();
        //开启事务
        tx = session.beginTransaction();
    }

    @After
    public void closeConnection() {
        if (null != session && session.isOpen()){
            //关闭session
            session.close();
        }
    }

    /**
     * 全表查询
     */
    @Test
    public void testQuery1(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User";
        List<User> list = session.createQuery(hql,User.class).getResultList();

        list.forEach(System.out::println);
        tx.commit();

    }

    /**
     * 条件查询，和下面的list不同，如果查不到记录，不会抛异常。
     */
    @Test
    public void testQuery2(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User where id = 94";
        Query query = session.createQuery(hql);
        User user = (User) query.uniqueResult();
        System.out.println(user);
        tx.commit();
    }

    /**
     * 条件查询2  ,使用list,如果查不到记录，会抛异常。
     */
    @Test
    public void testQuery8(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User where id = 94";
        Query query = session.createQuery(hql);
        User user = (User) query.list().get(0);
        System.out.println(user);
        tx.commit();
    }

    /**
     * 条件查询3  ,使用?预编译。
     */
    @Test
    public void testQuery9(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User where id = ?0 and username = ?1";
        Query query = session.createQuery(hql);
        query.setParameter(0,3);
        query.setParameter(1,"lizemin10");
        User user = (User) query.uniqueResult();
        System.out.println(user);
        tx.commit();
    }

    /**
     * 模糊查询
     */
    @Test
    public void testQuery3(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User where name like '%8%'";
        Query query = session.createQuery(hql);
        List<User> users = query.list();
        users.forEach(System.out::println);
        tx.commit();
    }

    /**
     * 排序,默认是升序，这里搞成降序
     */
    @Test
    public void testQuery4(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User order by id desc";
        Query query = session.createQuery(hql);
        List<User> users = query.list();
        users.forEach(System.out::println);
        tx.commit();
    }

    /**
     * 只查询某几个字段
     */
    @Test
    public void testQuery5(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        //这里需要注意的是：不要使用数据表中的name字段，而是要用User类中的username属性
        String hql = "select username from User a where id = 88";
        Query query = session.createQuery(hql);
        String name = (String)query.uniqueResult();
        System.out.println(name);
        tx.commit();
    }

    /**
     * 使用占位符
     */
    @Test
    public void testQuery6(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        //这里需要注意的是：不要使用数据表中的name字段，而是要用User类中的username属性
        String hql = "from User a where id = :id";
        Query query = session.createQuery(hql);
        query.setString("id","88");
        List<User> users = query.list();
        users.forEach(System.out::println);

        tx.commit();
    }

    /**
     * 分页查询
     */
    @Test
    public void testQuery7(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        //这里需要注意的是：不要使用数据表中的name字段，而是要用User类中的username属性
        String hql = "from User";
        Query query = session.createQuery(hql);

        //起始记录
        query.setFirstResult(1);
        //多少条记录
        query.setMaxResults(20);
        List<User> users = query.list();
        users.forEach(System.out::println);

        tx.commit();
    }

    /**
     * 条件查询4
     */
    @Test
    public void testQuery10(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "from User where id = :id and username = :username";
        Query query = session.createQuery(hql);
        query.setParameter("id",3);
        query.setParameter("username","lizemin10");
        User user = (User) query.uniqueResult();
        System.out.println(user);
        tx.commit();
    }

    /**
     * 聚合查询
     */
    @Test
    public void testQuery11(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "select count(*) from User";
        Query query = session.createQuery(hql);
        List<Long> list = query.list();
        Long count = list.get(0);
        System.out.println(count);
        tx.commit();
    }

    /**
     * 聚合查询2
     */
    @Test
    public void testQuery12(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "select count(*) from User";
        Query query = session.createQuery(hql);
        Long count = (Long) query.uniqueResult();
        System.out.println(count);
        tx.commit();
    }

    /**
     * 查询局部字段（投影查询）
     */
    @Test
    public void testQuery13(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "select username,birthday from User";
        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();
        for (Object[] objects : list) {
            for (Object object : objects) {
                System.out.print(object+"\t");
            }
            System.out.println();
        }

        tx.commit();
    }

    /**
     * 查询局部字段2（投影查询）---并且将返回结果封装成一个对象
     */
    @Test
    public void testQuery14(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "select new User(username,birthday) from User";
        Query query = session.createQuery(hql);
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

        tx.commit();
    }

    /**
     * 别名查询
     */
    @Test
    public void testQuery15(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        String hql = "select u from User u";
        Query query = session.createQuery(hql);
        List<User> list = query.list();
        for (User user : list) {
            System.out.println(user);
        }

        tx.commit();
    }

    // 测试使用ctags的跳转功能
    public void testQuery16(){
        //idea会针对from报错，不要管它，实际上是可以执行成功的
        testQuery12();
    }
    










}
